// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_BOOST_XML_NODE_PRED_H_
#define LIBV_BOOST_XML_NODE_PRED_H_

#include <deque>
#include <string>
#include <libv/boost/xml/xml_node.h>



namespace libv {

class NodePred {
  private:
    typedef ::std::deque< ::std::string > Names;

  public:
    NodePred()
        : invert_(false) {}

    explicit NodePred(const ::std::string& name)
      : names_(1, name),
        invert_(false) {}

    NodePred(const char* name1,
             const char* name2)
      : invert_(false) {
        names_.push_back(name1);
        names_.push_back(name2);
    }

    NodePred(const ::std::string& name1,
            const ::std::string& name2)
      : invert_(false) {
        names_.push_back(name1);
        names_.push_back(name2);
    }

    NodePred(const ::std::string& name1,
             const ::std::string& name2,
             const ::std::string& name3)
      : invert_(false) {
        names_.push_back(name1);
        names_.push_back(name2);
        names_.push_back(name3);
    }

    template<class TStringIterator>
    NodePred(const TStringIterator& begin, const TStringIterator& end)
      : names_(begin, end),
        invert_(false) {}

    bool operator()(const libv::XmlNode& node) const {
        if ( !names_.empty() ) {
            const ::std::string& name = node.Name();
            for ( Names::const_iterator \
                  i = names_.begin() ; i != names_.end() ; ++i ) {
                if ( *i == name ) {
                    return !invert_;
                }
            }
        }
        return invert_;
    }

    NodePred operator!() const {
        return NodePred(names_, !invert_);
    }

  private:
    NodePred(const Names& names, const bool invert)
        : names_(names),
          invert_(invert) {}

    Names names_;
    bool invert_;
};

}  // libv

#endif  // LIBV_BOOST_XML_NODE_PRED_H_
